import 'dart:collection';

import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:flutter/services.dart' show rootBundle;
import 'support_config.dart';

 class WXLang {
   static String relativePath = "./assets/local/";
   Locale _locale;
   static WXLang _inst;
   static LanguageConfig _appConfig;
   static List<String> _paths;
   static LinkedHashMap<String, Map> _multipleLang; /// 缓存多语言切换时的转换文件，避免每次切换都重新读取json0配置
   static HashMap<String, dynamic> _langCache; /// 根据package去缓存解析的json文件，这样读取过程中可以根据package读取，提高读取速度
   ///

   WXLang(this._locale);

   static Future<WXLang> init(Locale locale, {LanguageConfig config, List<String> paths}) async {
     if(locale == null || paths == null) return null;
     print("远远====远远");

     _appConfig = config;
     _paths = paths;
     _inst = WXLang(locale);
     _multipleLang ??= LinkedHashMap();

     await getLanguageJson();

     return _inst;
   }

   static Future<WXLang> load(Locale locale) async {
     if(locale == null || _paths == null) return null;

     _inst = WXLang(locale);

     await getLanguageJson();

     return _inst;
   }

   static Future getLanguageJson() async {
     if (_langCache != null) {
       _langCache.clear();
       _langCache = null;
     }
     _langCache ??= HashMap();
     Locale _temLocale = _inst._locale;

//     wxLog('默认语种为: ${_temLocale.languageCode}');

     if(_multipleLang != null && _multipleLang.containsKey(_temLocale.languageCode)) {
       _langCache = _multipleLang[_temLocale.languageCode];
       return;
     }

     String jsonLang;  /// 承载配置的json 字典
     ///

     _paths.forEach((path) async {
       try {
         jsonLang = await rootBundle.loadString('$path${_temLocale.languageCode}.json');

         print("path: $path,  jsonLang: $jsonLang");
       } catch (e) {
//       wxLog("获取语言包失败");
         _inst._locale = Locale(_appConfig.defaultLanguage()["code"]);

         jsonLang = await rootBundle.loadString('$path${_inst._locale.languageCode}.json');
       }

       Map<String, dynamic> jsonLanguage = json.decode(jsonLang);
       String package = path.split('/')[1];

       _langCache[package] = jsonLanguage;
     });

     if (_langCache.isNotEmpty) {
       _multipleLang[_temLocale.languageCode] = _langCache;
     }

//     wxLog("当前语音为: ${_inst._locale}");
//     wxLog("对应的语言包为: $jsonLanguage");
   }

   static String $t(String key, {String package}) {
     if ( key == null || key.isEmpty || _langCache == null || _langCache.isEmpty) return "";

     var _array = key.split(".");

     Map<String, dynamic> _jsonLanguage;

     if(package != null && package.isNotEmpty) {
       _jsonLanguage = _langCache[package];

       if(_jsonLanguage == null)  return "";

       Map<String, dynamic> result =_searchValueByKey(_array,key, _jsonLanguage);

       return result == null || !result.containsKey('value') ? '' : result['value'];
     }

     for(int i=0, j= _langCache.length; i < j; i++) {
       _jsonLanguage = _langCache[_langCache.keys.toList()[i]];
       if(_jsonLanguage == null) continue;

       Map<String, dynamic> result =_searchValueByKey(_array,key, _jsonLanguage);

       if(result != null && result['flag'] == true) {
         return result['value'];
       } else {
         continue;
       }
     }


//     var _dict  = _jsonLanguage;
//
//     var _retValue = '';
//
//     try {
//       _array.forEach((itemKey) {
//              if (_dict[itemKey].runtimeType == null) {
//                _retValue = key;
//
//                return;
//              }
//
//              if (_dict[itemKey].runtimeType != String) {
//                _dict = _dict[itemKey];
//              } else {
//                _retValue = _dict[itemKey];
//              }
//            });
//
//       _retValue = _retValue.isEmpty ? _dict : _retValue;
//     } catch (e) {
//
//       _retValue = "cann't get value";
//     }
//
//     return _retValue ?? "";

     return "";
   }

   static Map<String, dynamic> _searchValueByKey(List<String> _array, String key, Map<String, dynamic> jsonLanguage) {
      if(key == null || jsonLanguage == null) return null;

      var _dict  = jsonLanguage;

      var _retValue = '';
      bool _searchFlag = false;

      try {
        _array.forEach((itemKey) {
          if (_dict[itemKey].runtimeType == null) { ///取出的value值为空
            _retValue = key;

            return;
          }

          if (_dict[itemKey].runtimeType != String) { /// 取出的值是一个字典
            _dict = _dict[itemKey];
            _searchFlag = _dict != null;
          } else {
            _retValue = _dict[itemKey];
            _searchFlag = _retValue != null && _retValue.isNotEmpty;
          }
        });

        _retValue = _retValue.isEmpty ? _dict : _retValue;
      } catch (e) {
        _searchFlag = false;
        _retValue = "cann't get value";
      }

      return {
        'value': _retValue ?? "",
        'flag': _searchFlag
      };
   }

 }



 class AppLocalizationsDelegate extends LocalizationsDelegate<WXLang> {
   final Locale locale;
   final LanguageConfig config;
   final List<String> paths;

   AppLocalizationsDelegate({@required this.config,@required this.paths,this.locale, });

   @override
  bool isSupported(Locale locale) {
    return config.supportLanguage().keys.toList().contains(locale.languageCode);
  }

  /// 初始化语言包文件
  @override
  Future<WXLang> load(Locale locale) async {
    return await WXLang.init(locale, config: config, paths: paths);
  }

  @override
  bool shouldReload(LocalizationsDelegate<WXLang> old) {
    return false;
  }
 }

 class SpecificLocalizationDelegate extends LocalizationsDelegate<WXLang> {
  final Locale overriddenLocale;

  SpecificLocalizationDelegate(this.overriddenLocale);

  @override
  bool isSupported(Locale locale) {
    return overriddenLocale != null;
  }

  /// 初始化语言包文件
  @override
  Future<WXLang> load(Locale locale) async {
    return await WXLang.load(overriddenLocale);
  }

  @override
  bool shouldReload(LocalizationsDelegate<WXLang> old) {
    return true;
  }
}